package com.qdhh.enrollment.common;

import cn.dev33.satoken.exception.NotLoginException;
import com.qdhh.enrollment.security.AuthException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * Centralised exception handling for REST controllers.
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(AuthException.class)
    public Result<Void> handleAuthException(AuthException ex) {
        log.warn("Auth exception: {}", ex.getMessage());
        return Result.failure(HttpStatus.UNAUTHORIZED.value(), "UNAUTHORIZED");
    }

    @ExceptionHandler(NotLoginException.class)
    public Result<Void> handleNotLoginException(NotLoginException ex) {
        // 统一处理Sa-Token的未登录异常，包括token缺失、过期、格式错误等情况
        // 统一返回401状态码，避免500错误
        String message = ex.getMessage();
        if (message != null && message.contains("前缀")) {
            // 如果是前缀错误，转换为标准的未登录消息
            message = "未登录或登录已过期";
        } else if (message == null || message.isEmpty()) {
            message = "未登录或登录已过期";
        }
        log.debug("NotLoginException: {}", message);
        return Result.failure(HttpStatus.UNAUTHORIZED.value(), message);
    }

    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusinessException(BusinessException ex) {
        log.warn("Business exception: {}", ex.getMessage());
        return Result.failure(ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValidationException(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getAllErrors().stream()
            .findFirst()
            .map(error -> error.getDefaultMessage() == null ? "参数校验失败" : error.getDefaultMessage())
            .orElse("参数校验失败");
        log.warn("Validation error: {}", message);
        return Result.failure(HttpStatus.BAD_REQUEST.value(), message);
    }

    @ExceptionHandler(Exception.class)
    public Result<Void> handleOtherException(Exception ex) {
        log.error("Unhandled exception: {}", ex.getMessage(), ex);
        // 开发环境显示详细错误信息，生产环境显示通用错误
        String message = "服务器内部错误";
        if (ex.getCause() != null) {
            message = ex.getCause().getMessage();
        } else if (ex.getMessage() != null) {
            message = ex.getMessage();
        }
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), message);
    }
}
